package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstant;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DeviceLocationTypeEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private Client client;

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 同步数据
     */
    @Override
    public void syncProductList() {
        //请求参数
        QueryProductListRequest request = new QueryProductListRequest();
        request.setPageSize(200);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        //调用第三方查询产品列表
        QueryProductListResponse response;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        //判断，如果数据为空，则中断请求
        if(!response.getBody().success){
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }

        //获取数据，存储到redis
        List<ProductVo> productVoList = response.getBody().getData().getList().getProductInfo().stream().map(
                p -> BeanUtil.toBean(p, ProductVo.class)
        ).collect(Collectors.toList());
        //存储到redis
        redisTemplate.boundValueOps(CacheConstant.ALL_PRODUCT_KEY).set(JSONUtil.toJsonStr(productVoList));
    }


    /**
     * 查询所有产品列表
     * @return 产品列表
     */
    @Override
    public List<ProductVo> allProduct() {


        //从缓存中获取数据
        String jsonStr =  redisTemplate.boundValueOps(CacheConstant.ALL_PRODUCT_KEY).get();
        //如果为空，返回空集合
        if(StringUtil.isEmpty(jsonStr)){
            return Collections.emptyList();
        }
        //转换数据，并返回
        return JSONUtil.toList(jsonStr,ProductVo.class);
    }

    @Override
    public void add(DeviceDto deviceDto) {
        //1.根据设备名称查询是否存在
       Integer count = deviceMapper.countDeviceName(deviceDto.getDeviceName());
       if(count > 0){
               throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
       }

        //2.Iot 注册设备
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse response = null;
        try {
             response = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            e.printStackTrace();

            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        if(!response.getBody().getSuccess()||response.getBody()==null){
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //新增设备后获取IotId
        String iotId = response.getBody().getData().getIotId();
        //3.准备需要保存到表中的数据
        Device device = BeanUtil.toBean(deviceDto,Device.class);
        device.setIotId(iotId);
        //3.1从Iot 获取产品的名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryProductResponse queryProductResponse = null;
        try {
             queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            e.printStackTrace();
            //删除第二部新增设备
            deleteDevice(iotId);
            throw new BaseException(BasicEnum.IOT_QUERY_PRODUCT_ERROR);
        }
        if(!queryProductResponse.getBody().getSuccess()||queryProductResponse.getBody()==null){
            //删除第二部新增设备
            deleteDevice(iotId);
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        device.setProductName(queryProductResponse.getBody().getData().getProductName());
        //3.2判断位置类型

        if(deviceDto.getLocationType() == DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal()){
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());

        }

        //4.保存到数据库
        try {
            deviceMapper.insertSelective(device);
        } catch (Exception e) {
            e.printStackTrace();
            deleteDevice(iotId);
        }



        //4.1如果抛异常，则删除第二部新增设备
    }

    //分页查询
    @Override
    public PageResponse<DeviceVo> pagequerydevice(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(),devicePageQueryDto.getPageSize());
       Page<DeviceVo>deviceVoPage = (Page<DeviceVo>)deviceMapper.findList(devicePageQueryDto.getDeviceName(),devicePageQueryDto.getProductKey(),devicePageQueryDto.getLocationType());
       return PageResponse.of(deviceVoPage,DeviceVo.class);
    }

    @Override
    public DeviceVo QueryDeviceDetail(QueryDeviceDetailRequest request) {
        //先从Iot查询设备详情
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDeviceDetailResponse queryDeviceDetailResponse = null;
        try {
             queryDeviceDetailResponse = client.queryDeviceDetail(request);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_SERVICE_DATA_ERROR);
        }
        if(!queryDeviceDetailResponse.getBody().getSuccess()||queryDeviceDetailResponse.getBody()==null){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_SERVICE_DATA_ERROR);
        }
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData DeviceDeta = queryDeviceDetailResponse.getBody().getData();

        //把DeviceDeta属性复制到DeviceVo
        DeviceVo deviceVo = BeanUtil.toBean(DeviceDeta,DeviceVo.class);
        //查询mysql中的设备
        DeviceVo deviceVo1 = deviceMapper.selectByIotId(request.getIotId());

        //开始合并两个Vo

        BeanUtil.copyProperties(deviceVo1,deviceVo, CopyOptions.create().ignoreNullValue());


        return deviceVo;
    }

    @Override
    public QueryThingModelPublishedResponseBody.QueryThingModelPublishedResponseBodyData queryThingModelPublished(QueryThingModelPublishedRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            QueryThingModelPublishedResponse response = client.queryThingModelPublished(request);
            return response.getBody().getData();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BasicEnum.IOT_QUERY_THING_MODEL_PUBLISHED_ERROR);
        }


    }

    @Override
    public QueryDevicePropertyStatusResponseBody.QueryDevicePropertyStatusResponseBodyData queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        try {
            QueryDevicePropertyStatusResponse response = client.queryDevicePropertyStatus(request);
            return response.getBody().getData();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
    }


    private void deleteDevice(String iotId){//设备Id
        DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
        deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        deleteDeviceRequest.setIotId(iotId);

        try {
            client.deleteDevice(new DeleteDeviceRequest());
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
    }


}